/*
 * Copyright 2010 Michael Nitsche
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.mnit.basis.db.sys;

import de.mnit.basis.db.sql.DBHilfe;
import de.mnit.basis.fehler.Fehler;


/**
 * @author Michael Nitsche
 * 04.04.2007	Erstellt
 *
 * TODO Verbindung erst herstellen, wenn benötigt! Gibt mehr Möglichkeiten!
 */
public class DBSysTabs {

	private static final String F_SYS_VERSION  ="dbsys";
	private static final String F_DB_NAME      ="name";
	private static final String F_DB_VERSION   ="version";
	private static final String F_TAB_VERSIONEN="tab_versionen";

	private final S_DBManager dbm;
	private final DBKonfigTab dbk;
	private final DBKonfigTab dbkt;


	public DBSysTabs(S_DBManager dbm, String name) {
		this(dbm, name, false);
	}

	public DBSysTabs(S_DBManager dbm, String name, boolean tabvers) {
		if(!dbm.gVerbunden())
			Fehler.sonstige.da_Verboten("Keine Verbindung zur Datenbank!");
		this.dbm=dbm;
		this.dbk=new DBKonfigTab(dbm, "dbsys");
		if(this.dbk.gNeuAngelegt())
			iAnlegen(name);

		if(tabvers)
			this.dbk.setze(F_TAB_VERSIONEN, 1);

		Integer i=this.dbk.gibInt(F_TAB_VERSIONEN);
		if(i!=null && i==1)
			this.dbkt=new DBKonfigTab(dbm, "dbsys_tabs");
		else
			this.dbkt=null;

		iUpdate(iSysVersion(), name);

		iPruefeName(name);
	}


	public int gDBVersion() {
		Integer version=this.dbk.gibInt(F_DB_VERSION);
		if(version==null)
			return 0;
		return version;
	}

	public void sDBVersion(int version_neu) {
		Fehler.zahl.wenn_ZuKlein(1, version_neu);
		int version_akt=gDBVersion();
		if(version_neu > version_akt)
			this.dbk.setze(F_DB_VERSION, version_neu);
	}

	public int gTabVersion(String tab) {
		tab=tab.trim().toLowerCase();
		boolean existiert=DBHilfe.existiert(this.dbm.direkt(), tab);
		if(this.dbkt==null)
			return existiert ? 1 : 0;

		Integer version=this.dbkt.gibInt(tab);

		if(existiert) {
			if(version==null) {
				this.dbkt.setze(tab, 1);  //sTabVersion führt hier zu einem Kreis!
				return 1;
			}
			else
				return version;
		}
		else {
			if(version!=null)
				this.dbkt.setze(tab, null);
			return 0;
		}
	}

	public void sTabVersion(String tab, int version_neu) {
		if(this.dbkt==null)
			if(version_neu != 1)
				Fehler.sonstige.da_Verboten("TabVersion muß erst aktiviert werden!");
			else
				return;

		tab=tab.trim().toLowerCase();
		Fehler.zahl.wenn_ZuKlein(1, version_neu);
		int version_akt=gTabVersion(tab);
		if(version_neu > version_akt)
			this.dbkt.setze(tab, version_neu);
	}

	// INTERN

	private void iAnlegen(String name) {
		iUpdate(0, name);
	}

	private int iSysVersion() {
		Integer version=this.dbk.gibInt(F_SYS_VERSION);
		if(version==null) return 1;
		Fehler.zahl.wenn_NichtInListe(version, 2);
		return version;
	}

	private void iUpdate(int akt_version, String db_name) {
		if(akt_version==0) { //Neu angelegt!
			this.dbk.setze(F_DB_VERSION, "0");
			this.dbk.setze(F_DB_NAME, db_name);
			akt_version=1;
		}
		if(akt_version==1) {
			this.dbk.setze(F_SYS_VERSION, "2");
			this.dbk.setze(F_TAB_VERSIONEN, "0");
			akt_version=2;
		}
		if(akt_version==2)
			return;
		Fehler.sonstige.da_Untypisch("Ungültige Versionsnummer für Update!");
	}

	private void iPruefeName(String name) {
		String dbname=this.dbk.gib("name"); //this.dbm.direkt().gibString("SELECT wert FROM dbsys WHERE id='name'");
		if(!name.toLowerCase().equals(dbname.toLowerCase()))
			Fehler.direkt("DB-Kennung ist falsch!");
	}

}
